# encoding=utf-8
# MVVM架构中的model，逻辑处理及数据更新
# BingoLee 2024-04-19
import os
from datetime import datetime

from utils.kit_profile import Profile
from utils.kit_utils import Log, Function
from viewmodel.kit_viewmodel import Topic, TopicBinder

from model.kit_data import cache
from model.server_data_parser import server_data_parser
from model.settings_processor import SettingsProcesser
from model.environment_handler import COMPortHandler, AppUpgradeHandler
from model.at_cmd_processor import CustomATCmdProcesser, ProjectATCmdProcesser, ATCmdParser


class Handler:
    """
    逻辑处理类
        1. 异步获取AT指令数据
        2. 异步加载首选项配置文件
        3. 定时更新com port并更新cache
    """

    @classmethod
    def init_start(cls):
        os.makedirs(Profile.logs_dir, exist_ok=True)
        Log.info(f'''
------------------------------------------------------------
-                    {Profile.app_name} v{Profile.app_version}                    -
------------------------------------------------------------''')
        # binding here
        TopicBinder.bind(Topic.APP_UPGRADE_START, AppUpgradeHandler.app_upgrade_handle_callback)
        TopicBinder.bind(Topic.SEND_AT_CMD_DATA, cls.at_cmd_handle_callback)
        TopicBinder.bind(Topic.ADD_CUSTOM_AT_CMD_DATA, cls.add_custom_at_cmd_data_callback)
        TopicBinder.bind(Topic.MOD_CUSTOM_AT_CMD_DATA, cls.mod_custom_at_cmd_data_callback)
        TopicBinder.bind(Topic.MOD_CUSTOM_AT_CMD_TAB, cls.mod_custom_at_cmd_tab_callback)
        TopicBinder.bind(Topic.DEL_CUSTOM_AT_CMD_DATA, cls.del_custom_at_cmd_data_callback)
        TopicBinder.bind(Topic.DEL_CUSTOM_AT_CMD_TAB, cls.del_custom_at_cmd_tab_callback)

    @classmethod
    def lazy_loding(cls):
        Function.create_thread(cls.load_data_from_local_and_server)
        # TODO: v0.0.1 only support log online page
        # Function.create_thread(COMPortHandler.update_comport_data)

    @classmethod
    def load_data_from_local_and_server(cls):
        # 1. load local settings file
        settings_data, err = SettingsProcesser.load_data()
        if settings_data is None:
            TopicBinder.notify(Topic.SHOW_MESSAGE_BOX, ('error', f"首选项配置文件异常:\n{err}", True))
            return
        TopicBinder.notify(Topic.SETTINGS_DATA_CHANGED, settings_data)
        """
        # 2. load local custom AT cmds
        custom_at_cmds, err = CustomATCmdProcesser.load_data()
        if custom_at_cmds is None:
            TopicBinder.notify(Topic.SHOW_MESSAGE_BOX, ('error', f"自定义AT指令文件异常:\n{err}", True))
            return
        TopicBinder.notify(Topic.CUSTOM_AT_CMDS_CHANGED, custom_at_cmds)
        """
        # 3. load data from socket server
        ret, err = server_data_parser.init_data()
        if not ret:
            TopicBinder.notify(Topic.SHOW_MESSAGE_BOX, ('error', f"从服务器加载全局数据失败:\n{err}", True))
            return
        """
        # 4. load project AT cmds
        project_at_cmds, err = ProjectATCmdProcesser.load_data()
        if project_at_cmds is None:
            TopicBinder.notify(Topic.SHOW_MESSAGE_BOX, ('error', f"项目AT指令数据异常:\n{err}", True))
            return
        TopicBinder.notify(Topic.PROJECT_AT_CMDS_CHANGED, project_at_cmds)
        """
        release_note, err = AppUpgradeHandler.get_version_and_release_note()
        if release_note is None:
            TopicBinder.notify(Topic.SHOW_MESSAGE_BOX, ('error', err, True))
            return
        if not release_note:    # no new version
            return
        TopicBinder.notify(Topic.SHOW_RELEASE_NOTE, release_note)

    @classmethod
    def at_cmd_handle_callback(cls, data):
        ret, err = ATCmdParser.is_invalid_at_cmd(data)
        if not ret:
            TopicBinder.notify(Topic.AT_CMD_RECV_DATA_CHANGED, (datetime.now(), ret, err))
            return
        TopicBinder.notify(Topic.AT_CMD_RECV_DATA_CHANGED, (datetime.now(), True, data))

    @classmethod
    def notify_custom_at_cmd_result(cls, result):
        ret, err = result
        if ret:
            TopicBinder.notify(Topic.CUSTOM_AT_CMDS_CHANGED, cache.get_custom_at_cmds())
        else:
            TopicBinder.notify(Topic.SHOW_MESSAGE_BOX, ('error', f"自定义AT指令操作异常:\n{err}", True))

    @classmethod
    def add_custom_at_cmd_data_callback(cls, data):
        cls.notify_custom_at_cmd_result(CustomATCmdProcesser.add_custom_at_cmd_data(data))

    @classmethod
    def mod_custom_at_cmd_data_callback(cls, data):
        cls.notify_custom_at_cmd_result(CustomATCmdProcesser.modify_custom_at_cmd_data(data))

    @classmethod
    def mod_custom_at_cmd_tab_callback(cls, data):
        cls.notify_custom_at_cmd_result(CustomATCmdProcesser.modify_custom_at_cmd_tab(data))

    @classmethod
    def del_custom_at_cmd_data_callback(cls, data):
        cls.notify_custom_at_cmd_result(CustomATCmdProcesser.del_custom_at_cmd_data(data))

    @classmethod
    def del_custom_at_cmd_tab_callback(cls, data):
        cls.notify_custom_at_cmd_result(CustomATCmdProcesser.del_custom_at_cmd_tab(data))
